package com.ng.framework.util;

import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.nio.charset.Charset;
import java.util.List;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

public abstract class NGDesktopUtil {

	public static final String LICENCIA_INVALIDA = "S/D";
	public static final String LICENCIA_NORMATIVAS = "Normativas";
	public static final String LICENCIA_TOTAL = "Obligaciones";

	private static Logger LOG = Logger.getLogger(NGDesktopUtil.class);

	public static List<String> getVMArguments() {

		RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();

		return runtimeMxBean.getInputArguments();

	}

	public static String getVMArgument(String vmArgument) {

		RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();

		for (String inputArgument : runtimeMxBean.getInputArguments()) {

			String[] data = inputArgument.split("=");

			if (vmArgument.equals(data[0])) {
				return data[1];
			}
		}

		return null;

	}

	public static String getMacAddress() {
		try {
			InetAddress address = InetAddress.getLocalHost();
			// InetAddress address = InetAddress.getByName("192.168.46.53");

			/*
			 * Get NetworkInterface for the current host and then read the hardware address.
			 */
			NetworkInterface ni = NetworkInterface.getByInetAddress(address);
			if (ni != null) {
				byte[] mac = ni.getHardwareAddress();
				if (mac != null) {
					/*
					 * Extract each array of mac address and convert it to hexa with the following format 08-00-27-DC-4A-9E.
					 */

					StringBuilder sb = new StringBuilder();

					for (int i = 0; i < mac.length; i++) {
						sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
					}

					return sb.toString();

				} else {
					LOG.error("Address doesn't exist or is not " + "accessible.");
				}
			} else {
				LOG.error("Network Interface for the specified " + "address is not found.");
			}
		} catch (Exception e) {
			LOG.error(e);
		}

		return null;
	}

	/**
	 * Algoritmo que devuelve un hash de instalación de acuerdo a ciertos valores del equipo al momento de la instalacion.
	 * 
	 * @return Installation Id
	 */
	public static String getInstallationId() {

		File appContext = new File(System.getProperty("configuration.path") + File.separator + "ng.properties");

		if (appContext.exists()) {

			String lastModified = String.valueOf(appContext.lastModified());

			LOG.info("Last Modified:" + lastModified);

			return lastModified;

		}

		return "Error";
	}
	/**
	 * Algoritmo que devuelve el tipo de licencia en base a un código recibido. Para ello verifica si el Installation Id del sistema coincide con el Installation Id encodeado
	 * dentro del código de licencia. Si las validaciones son correctas devuelve el Tipo de Licencia, de lo contrario devuelve null
	 */
	public static String getTipoLicencia(String codigoLicencia) {

		Charset charset = Charset.forName("UTF-16");
		String separator = "ng-2013";

		byte[] codigoLicenciaBytesDecoded = Base64.decodeBase64(codigoLicencia);
		String codigoLicenciaDecoded = new String(codigoLicenciaBytesDecoded, charset);

		String[] split = codigoLicenciaDecoded.split(separator);

		if (split.length != 3) {
			return null;
		}

		byte[] claveInstalacionBytesDecoded = Base64.decodeBase64(split[0]);

		String claveInstalacionDecoded = new String(claveInstalacionBytesDecoded, charset);

		byte[] tipoLicenciaBytesDecoded = Base64.decodeBase64(split[1]);

		String tipoLicenciaDecoded = new String(tipoLicenciaBytesDecoded, charset);

		byte[] fechaHastaBytesDecoded = Base64.decodeBase64(split[2]);

		String fechaHastaDecoded = new String(fechaHastaBytesDecoded, charset);
		//String fechaHastaDecoded = "24/10/2015";

		/*
		 * Si la fecha de licencia ha excedido lo permitido devolvemos una licencia nula
		 */
		if (NGDateUtil.parseDate(fechaHastaDecoded, NGDateUtil.ddMMyyyy_dateFormat).before(NGDateUtil.getNow())) {
			LOG.info("License Expired:" + fechaHastaDecoded);
			return null;
		}

		if (claveInstalacionDecoded.equals(NGDesktopUtil.getInstallationId())) {
			return tipoLicenciaDecoded;
		}

		return null;

	}

	/**
	 * Algoritmo que chequea ante todo si hay una licencia en el sistema, de lo contratio devuelve null. De existir la licencia, devuelve el tipo de licencia asociada a través del
	 * método getTipoLicencia.
	 * 
	 * @return Código de Licencia del Sistema.
	 * @throws IOException
	 */

	public static String getCodigoLicenciaInstalacion() throws IOException {

		Charset charset = Charset.forName("UTF-16");

		File license = new File(System.getProperty("configuration.path") + File.separator + "ense.tmp");

		if (license.exists()) {

			String codigoLicencia = FileUtils.readFileToString(license, charset);

			String tipoLicencia = getTipoLicencia(codigoLicencia);

			if (tipoLicencia != null) {
				return codigoLicencia;
			}

		}

		return null;

	}

	public static void saveCodigoLicenciaInstalacion(String codigoLicencia) throws IOException {

		Charset charset = Charset.forName("UTF-16");

		File license = new File(System.getProperty("configuration.path") + File.separator + "ense.tmp");

		FileUtils.writeStringToFile(license, codigoLicencia, charset);
	}

	public static void main(String[] args) {
		getInstallationId();
	}

}
